package pbft

import (
	"blockchain/public/function"
	"crypto/sha256"
	"encoding/json"
)

type prepareMessage struct {
	tradesHash [32]byte
	sign string
	nodeSeq int
}

func prepare(nodeSeq int){
	var hash [32]byte
	var prepare prepareMessage
	prepare.nodeSeq=nodeSeq
	h:=pre_prepareData(nodeSeq)
	if hash!=h{
		hash=h
	}
	prepare.tradesHash=hash
	prepare.sign=function.SignHash(prepare.tradesHash,prepare.nodeSeq)
	var flagPrepared=make(chan bool)
	go nodeSendPre_prepare(nodeSeq,prepare,flagPrepared)
	<-flagPrepared
	//fmt.Println(prepare.tradesHash)
}

func nodeSendPre_prepare(nodeSeq int,prepare prepareMessage,flagPrepared chan bool){
	for i:=0;i<N;i++{
		select {
		case chanRecPrepare[i]<-prepare:FlagPrepared[nodeSeq][i]<-true
		close(FlagPrepared[nodeSeq][i])
		default:FlagPrepared[nodeSeq][i]<-false
			close(FlagPrepared[nodeSeq][i])
		}
	}
	flagPrepared<-true
	close(flagPrepared)

}

func pre_prepareData(nodeSeq int)[32]byte{
	var pre_prepare pre_prepareMessage
	var hash [32]byte
	pre_prepare=<-chanRecPre_prepare[nodeSeq]
	t:=pre_prepare.trades
	pre_prepare.trades=orderTrades(pre_prepare.trades)
	tradeSet[nodeSeq]=pre_prepare.trades
	if t==pre_prepare.trades{
		data,_:=json.Marshal(pre_prepare.trades)
		res:=function.VerifySign(data,pre_prepare.sign,pre_prepare.priSeq)
		if res&&pre_prepare.sequence==currentTradeSeq&&pre_prepare.view==View{
			hash=sha256.Sum256(data)
		}
	}
	return hash
}
